package org.mozhu.mboot.backend.config;

import org.apache.commons.lang3.StringUtils;
import org.mozhu.mboot.backend.security.*;
import org.mozhu.mboot.backend.system.account.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.core.GrantedAuthorityDefaults;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    JWTService jwtService;

    @Autowired
    UserService userService;

    /**
     * 白名单
     */
    private static final String[] WHITELIST_PATTERN = {
            "/logout",
            // -- register url
            "/users/signup",
            // -- swagger ui
            "/v2/api-docs",
            "/swagger-resources",
            "/swagger-resources/**",
            "/configuration/ui",
            "/configuration/security",
            "/swagger-ui.html",
            "/webjars/**"
            // other public endpoints of your API may be appended to this array
    };

    @Bean
    public CustomUserDetailsService customUserDetailsService() {
        return new CustomUserDetailsService();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public GrantedAuthorityDefaults GrantedAuthorityDefaults() {
        return new GrantedAuthorityDefaults(StringUtils.EMPTY);
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(customUserDetailsService()).passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 白名单过滤
        http.authorizeRequests()
                .antMatchers(WHITELIST_PATTERN).permitAll();

        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        // 登录
        JWTLoginFilter loginFilter = new JWTLoginFilter(jwtService, authenticationManager());

        // 鉴权
        JWTAuthenticationFilter authenticationFilter = new JWTAuthenticationFilter(jwtService, userService);

        http.cors().and().csrf().disable()
                .authorizeRequests()
                .anyRequest().authenticated() //任何请求,登录后可以访问
                .and()
                .addFilter(loginFilter)
                .addFilterAfter(authenticationFilter, JWTLoginFilter.class)
                .headers().frameOptions().disable()
                .and()
                .logout().logoutSuccessHandler(new JWTLogoutSuccessHandler()).permitAll(); //注销行为任意访问

    }

}
